package com.leantech.android.browser.ui

import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Bitmap
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.View
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.widget.ProgressBar
import androidx.core.animation.addListener
import com.leantech.android.browser.databinding.ActivitySimpleBrowserBinding
import com.leantech.android.browser.utils.gone
import com.leantech.android.browser.utils.visible
import com.leantech.android.browser.views.SimpleWebView
import com.qmuiteam.qmui.widget.webview.QMUIWebViewClient
import splitties.activities.start

class SimpleBrowserActivity : BaseActivity() {

    companion object {
        private const val KEY_URL = "url"
        private const val KEY_TITLE = "title"

        fun launch(context: Context, url: String, title: String? = null) {
            context.start<SimpleBrowserActivity> {
                putExtra(KEY_URL, url)
                putExtra(KEY_TITLE, title)
            }
        }
    }

    private lateinit var binding: ActivitySimpleBrowserBinding
    private lateinit var webView: SimpleWebView
    private lateinit var progressHandler: ProgressHandler
    private var title: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySimpleBrowserBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val url = intent.getStringExtra(KEY_URL) ?: ""
        title = intent.getStringExtra(KEY_TITLE)
        updateTitle(title)

        initView()

        if (url.isNotEmpty()) {
            webView.loadUrl(url)
        }

        showLoading()
    }

    private fun showLoading() {
        binding.loadingView.visible()
    }

    private fun hideLoading() {
        binding.loadingView.gone()
    }

    private fun updateTitle(title: String?) {
        if (title.isNullOrEmpty()) return
        this.title = title
        binding.layoutTopBar.setTitle(title)
    }

    private fun initView() {
        progressHandler = ProgressHandler(binding.progressBar)
        //init web view
        webView = SimpleWebView(this)
        webView.webChromeClient = HookWebViewChromeClient()
        webView.webViewClient = HookWebViewClient()
        webView.requestFocus(View.FOCUS_DOWN)

        binding.webViewContainer.addWebView(webView, false)

        binding.layoutTopBar.addLeftBackImageButton().setOnClickListener {
            finish()
        }
    }

    override fun onDestroy() {
        webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null)
        webView.clearHistory()
        binding.webViewContainer.removeView(webView)
        webView.destroy()

        super.onDestroy()

    }

    private fun sendProgressMsg(msgType: Int, progress: Int, duration: Int) {
        val msg = Message.obtain(progressHandler)
        msg.what = msgType
        msg.arg1 = progress
        msg.arg2 = duration

        progressHandler.sendMessage(msg)
    }

    private inner class HookWebViewChromeClient : WebChromeClient() {

        override fun onProgressChanged(view: WebView?, newProgress: Int) {
            super.onProgressChanged(view, newProgress)
            if (newProgress > binding.progressBar.progress) {
                sendProgressMsg(ProgressHandler.PROGRESS_PROCESS, newProgress, 100)
            }
        }

        override fun onReceivedTitle(view: WebView?, title: String?) {
            super.onReceivedTitle(view, title)
//            updateTitle(title)
        }

        override fun onShowCustomView(view: View?, callback: CustomViewCallback?) {
            callback?.onCustomViewHidden()
        }
    }

    private inner class HookWebViewClient : QMUIWebViewClient(false, true) {

        override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
            super.onPageStarted(view, url, favicon)
            if (title.isNullOrEmpty()) {
                updateTitle(view?.title)
            }

            if (binding.progressBar.progress == 0) {
                sendProgressMsg(ProgressHandler.PROGRESS_PROCESS, 30, 500)
            }
        }

        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            hideLoading()
            sendProgressMsg(ProgressHandler.PROGRESS_GONE, 100, 0)
            if (title.isNullOrEmpty()) {
                updateTitle(view?.title)
            }
        }
    }

    private class ProgressHandler(
        private val progressBar: ProgressBar, looper: Looper = Looper.getMainLooper()
    ) : Handler(looper) {

        companion object {
            internal const val PROGRESS_PROCESS = 1
            internal const val PROGRESS_GONE = 2
        }

        private var dstProgressIndex: Int = 0
        private var progressDuration = 0
        private var animator: ObjectAnimator? = null

        override fun handleMessage(msg: Message) {
            when (msg.what) {
                PROGRESS_PROCESS -> {
                    dstProgressIndex = msg.arg1
                    progressDuration = msg.arg2
                    progressBar.visibility = View.VISIBLE
                    if (animator?.isRunning == true) {
                        animator?.cancel()
                    }

                    animator =
                        ObjectAnimator.ofInt(progressBar, "progress", dstProgressIndex).apply {
                            duration = progressDuration.toLong()
                            addListener(onEnd = {
                                if (progressBar.progress == 100) {
                                    sendEmptyMessageDelayed(PROGRESS_GONE, 500)
                                }
                            })

                        }

                    animator?.start()

                }

                PROGRESS_GONE -> {
                    dstProgressIndex = 0
                    progressDuration = 0
                    progressBar.progress = 0
                    progressBar.visibility = View.GONE
                    if (animator?.isRunning == true) {
                        animator?.cancel()
                    }

                    animator = ObjectAnimator.ofInt(progressBar, "progress", 0).apply {
                        duration = 0L
                        removeAllListeners()
                    }


                }

                else -> {
                    //do nothing.
                }
            }
        }
    }
}